Trò chơi Tic-Tac-Toe, game đánh caro full source code
- PhotonPlayer.cs
- PhotonNetwork /
- Plugins /
- Photon Unity Networking /
- Assets /
- project /
2 // <copyright file="PhotonPlayer.cs" company="Exit Games GmbH">
3 // PhotonNetwork Framework for Unity - Copyright (C) 2011 Exit Games GmbH
4 // </copyright>
5 // <summary>
6 // Represents a player, identified by actorID (a.k.a. ActorNumber).
7 // Caches properties of a player.
8 // </summary>
9 // <author>developer@exitgames.com</author>
10 // ----------------------------------------------------------------------------
11
12 using System.Collections.Generic;
13 using ExitGames.Client.Photon;
14 using UnityEngine;
15 using Hashtable = ExitGames.Client.Photon.Hashtable;
16
17
18 /// <summary>
19 /// Summarizes a "player" within a room, identified (in that room) by actorID.
20 /// </summary>
21 /// <remarks>
22 /// Each player has an actorId (or ID), valid for that room. It's -1 until it's assigned by server.
23 /// Each client can set it's player's custom properties with SetCustomProperties, even before being in a room.
24 /// They are synced when joining a room.
25 /// </remarks>
26 /// \ingroup publicApi
27 public class PhotonPlayer
28 {
29 /// <summary>This player's actorID</summary>
30 public int ID
31 {
32 get { return this.actorID; }
33 }
34
35 /// <summary>Identifier of this player in current room.</summary>
36 private int actorID = -1;
37
38 private string nameField = "";
39
40 /// <summary>Nickname of this player.</summary>
41 public string name {
42 get
43 {
44 return this.nameField;
45 }
46 set
47 {
48 if (!isLocal)
49 {
50 Debug.LogError("Error: Cannot change the name of a remote player!");
51 return;
52 }
53
54 this.nameField = value;
55 }
56 }
57
58 /// <summary>Only one player is controlled by each client. Others are not local.</summary>
59 public readonly bool isLocal = false;
60
61 /// <summary>
62 /// The player with the lowest actorID is the master and could be used for special tasks.
63 /// </summary>
64 public bool isMasterClient
65 {
66 get { return (PhotonNetwork.networkingPeer.mMasterClient == this); }
67 }
68
69 /// <summary>Read-only cache for custom properties of player. Set via Player.SetCustomProperties.</summary>
70 /// <remarks>
71 /// Don't modify the content of this Hashtable. Use SetCustomProperties and the
72 /// properties of this class to modify values. When you use those, the client will
73 /// sync values with the server.
74 /// </remarks>
75 public Hashtable customProperties { get; private set; }
76
77 /// <summary>Creates a Hashtable with all properties (custom and "well known" ones).</summary>
78 /// <remarks>If used more often, this should be cached.</remarks>
79 public Hashtable allProperties
80 {
81 get
82 {
83 Hashtable allProps = new Hashtable();
84 allProps.Merge(this.customProperties);
85 allProps[ActorProperties.PlayerName] = this.name;
86 return allProps;
87 }
88 }
89
90 /// <summary>Can be used to store a reference that's useful to know "by player".</summary>
91 /// <remarks>Example: Set a player's character as Tag by assigning the GameObject on Instantiate.</remarks>
92 public object TagObject;
93
94
95 /// <summary>
96 /// Creates a PhotonPlayer instance.
97 /// </summary>
98 /// <param name="isLocal">If this is the local peer's player (or a remote one).</param>
99 /// <param name="actorID">ID or ActorNumber of this player in the current room (a shortcut to identify each player in room)</param>
100 /// <param name="name">Name of the player (a "well known property").</param>
101 public PhotonPlayer(bool isLocal, int actorID, string name)
102 {
103 this.customProperties = new Hashtable();
104 this.isLocal = isLocal;
105 this.actorID = actorID;
106 this.nameField = name;
107 }
108
109 /// <summary>
110 /// Internally used to create players from event Join
111 /// </summary>
112 internal protected PhotonPlayer(bool isLocal, int actorID, Hashtable properties)
113 {
114 this.customProperties = new Hashtable();
115 this.isLocal = isLocal;
116 this.actorID = actorID;
117
118 this.InternalCacheProperties(properties);
119 }
120
121 /// <summary>
122 /// Makes PhotonPlayer comparable
123 /// </summary>
124 public override bool Equals(object p)
125 {
126 PhotonPlayer pp = p as PhotonPlayer;
127 return (pp != null && this.GetHashCode() == pp.GetHashCode());
128 }
129
130 public override int GetHashCode()
131 {
132 return this.ID;
133 }
134
135 /// <summary>
136 /// Used internally, to update this client's playerID when assigned.
137 /// </summary>
138 internal void InternalChangeLocalID(int newID)
139 {
140 if (!this.isLocal)
141 {
142 Debug.LogError("ERROR You should never change PhotonPlayer IDs!");
143 return;
144 }
145
146 this.actorID = newID;
147 }
148
149 /// <summary>
150 /// Caches custom properties for this player.
151 /// </summary>
152 internal void InternalCacheProperties(Hashtable properties)
153 {
154 if (properties == null || properties.Count == 0 || this.customProperties.Equals(properties))
155 {
156 return;
157 }
158
159 if (properties.ContainsKey(ActorProperties.PlayerName))
160 {
161 this.nameField = (string)properties[ActorProperties.PlayerName];
162 }
163
164 this.customProperties.MergeStringKeys(properties);
165 this.customProperties.StripKeysWithNullValues();
166 }
167
168 /// <summary>
169 /// Updates and synchronizes the named properties of this Player with the values of propertiesToSet.
170 /// </summary>
171 /// <remarks>
172 /// Any player's properties are available in a Room only and only until the player disconnect or leaves.
173 /// Access any player's properties by: Player.CustomProperties (read-only!) but don't modify that hashtable.
174 ///
175 /// New properties are added, existing values are updated.
176 /// Other values will not be changed, so only provide values that changed or are new.
177 /// To delete a named (custom) property of this player, use null as value.
178 /// Only string-typed keys are applied (everything else is ignored).
179 ///
180 /// Local cache is updated immediately, other players are updated through Photon with a fitting operation.
181 /// To reduce network traffic, set only values that actually changed.
182 /// </remarks>
183 /// <param name="propertiesToSet">Hashtable of props to udpate, set and sync. See description.</param>
184 public void SetCustomProperties(Hashtable propertiesToSet)
185 {
186 if (propertiesToSet == null)
187 {
188 return;
189 }
190
191 // merge (delete null-values)
192 this.customProperties.MergeStringKeys(propertiesToSet); // includes a Equals check (simplifying things)
193 this.customProperties.StripKeysWithNullValues();
194
195 // send (sync) these new values
196 Hashtable customProps = propertiesToSet.StripToStringKeys() as Hashtable;
197 if (this.actorID > 0 && !PhotonNetwork.offlineMode)
198 {
199 PhotonNetwork.networkingPeer.OpSetCustomPropertiesOfActor(this.actorID, customProps, true, 0);
200 }
201 NetworkingPeer.SendMonoMessage(PhotonNetworkingMessage.OnPhotonPlayerPropertiesChanged, this, propertiesToSet);
202 }
203
204 /// <summary>
205 /// Try to get a specific player by id.
206 /// </summary>
207 /// <param name="ID">ActorID</param>
208 /// <returns>The player with matching actorID or null, if the actorID is not in use.</returns>
209 public static PhotonPlayer Find(int ID)
210 {
211 for (int index = 0; index < PhotonNetwork.playerList.Length; index++)
212 {
213 PhotonPlayer player = PhotonNetwork.playerList[index];
214 if (player.ID == ID)
215 {
216 return player;
217 }
218 }
219 return null;
220 }
221
222 public PhotonPlayer Get(int id)
223 {
224 return PhotonPlayer.Find(id);
225 }
226
227 public PhotonPlayer GetNext()
228 {
229 return GetNextFor(this.ID);
230 }
231
232 public PhotonPlayer GetNextFor(PhotonPlayer currentPlayer)
233 {
234 if (currentPlayer == null)
235 {
236 return null;
237 }
238 return GetNextFor(currentPlayer.ID);
239 }
240
241 public PhotonPlayer GetNextFor(int currentPlayerId)
242 {
243 if (PhotonNetwork.networkingPeer == null || PhotonNetwork.networkingPeer.mActors == null || PhotonNetwork.networkingPeer.mActors.Count < 2)
244 {
245 return null;
246 }
247
248 Dictionary<int, PhotonPlayer> players = PhotonNetwork.networkingPeer.mActors;
249 int nextHigherId = int.MaxValue; // we look for the next higher ID
250 int lowestId = currentPlayerId; // if we are the player with the highest ID, there is no higher and we return to the lowest player's id
251
252 foreach (int playerid in players.Keys)
253 {
254 if (playerid < lowestId)
255 {
256 lowestId = playerid; // less than any other ID (which must be at least less than this player's id).
257 }
258 else if (playerid > currentPlayerId && playerid < nextHigherId)
259 {
260 nextHigherId = playerid; // more than our ID and less than those found so far.
261 }
262 }
263
264 //UnityEngine.Debug.LogWarning("Debug. " + currentPlayerId + " lower: " + lowestId + " higher: " + nextHigherId + " ");
265 //UnityEngine.Debug.LogWarning(this.RoomReference.GetPlayer(currentPlayerId));
266 //UnityEngine.Debug.LogWarning(this.RoomReference.GetPlayer(lowestId));
267 //if (nextHigherId != int.MaxValue) UnityEngine.Debug.LogWarning(this.RoomReference.GetPlayer(nextHigherId));
268 return (nextHigherId != int.MaxValue) ? players[nextHigherId] : players[lowestId];
269 }
270
271 /// <summary>
272 /// Brief summary string of the PhotonPlayer. Includes name or player.ID and if it's the Master Client.
273 /// </summary>
274 public override string ToString()
275 {
276 if (string.IsNullOrEmpty(this.name))
277 {
278 return string.Format("#{0:00}{1}", this.ID, this.isMasterClient ? "(master)":"");
279 }
280
281 return string.Format("'{0}'{1}", this.name, this.isMasterClient ? "(master)" : "");
282 }
283
284 /// <summary>
285 /// String summary of the PhotonPlayer: player.ID, name and all custom properties of this user.
286 /// </summary>
287 /// <remarks>
288 /// Use with care and not every frame!
289 /// Converts the customProperties to a String on every single call.
290 /// </remarks>
291 public string ToStringFull()
292 {
293 return string.Format("#{0:00} '{1}' {2}", this.ID, this.name, this.customProperties.ToStringFull());
294 }
295 }
----------------------------------------------------------------------------
PhotonNetwork Framework for Unity - Copyright (C) 2011 Exit Games GmbH
Represents a player, identified by actorID (a.k.a. ActorNumber).
Caches properties of a player.
----------------------------------------------------------------------------
Summarizes a "player" within a room, identified (in that room) by actorID.
Each player has an actorId (or ID), valid for that room. It's -1 until it's assigned by server.
Each client can set it's player's custom properties with SetCustomProperties, even before being in a room.
They are synced when joining a room.
\ingroup publicApi
The player with the lowest actorID is the master and could be used for special tasks.
Don't modify the content of this Hashtable. Use SetCustomProperties and the
properties of this class to modify values. When you use those, the client will
sync values with the server.
Creates a PhotonPlayer instance.
If this is the local peer's player (or a remote one).
ID or ActorNumber of this player in the current room (a shortcut to identify each player in room)
Name of the player (a "well known property").
Internally used to create players from event Join
Makes PhotonPlayer comparable
Used internally, to update this client's playerID when assigned.
Caches custom properties for this player.
Updates and synchronizes the named properties of this Player with the values of propertiesToSet.
Any player's properties are available in a Room only and only until the player disconnect or leaves.
Access any player's properties by: Player.CustomProperties (read-only!) but don't modify that hashtable.
New properties are added, existing values are updated.
Other values will not be changed, so only provide values that changed or are new.
To delete a named (custom) property of this player, use null as value.
Only string-typed keys are applied (everything else is ignored).
Local cache is updated immediately, other players are updated through Photon with a fitting operation.
To reduce network traffic, set only values that actually changed.
Hashtable of props to udpate, set and sync. See description.
merge (delete null-values)
this.customProperties.MergeStringKeys(propertiesToSet); includes a Equals check (simplifying things)
send (sync) these new values
Try to get a specific player by id.
ActorID
int nextHigherId = int.MaxValue; we look for the next higher ID
int lowestId = currentPlayerId; if we are the player with the highest ID, there is no higher and we return to the lowest player's id
lowestId = playerid; less than any other ID (which must be at least less than this player's id).
nextHigherId = playerid; more than our ID and less than those found so far.
UnityEngine.Debug.LogWarning("Debug. " + currentPlayerId + " lower: " + lowestId + " higher: " + nextHigherId + " ");
UnityEngine.Debug.LogWarning(this.RoomReference.GetPlayer(currentPlayerId));
UnityEngine.Debug.LogWarning(this.RoomReference.GetPlayer(lowestId));
if (nextHigherId != int.MaxValue) UnityEngine.Debug.LogWarning(this.RoomReference.GetPlayer(nextHigherId));
Brief summary string of the PhotonPlayer. Includes name or player.ID and if it's the Master Client.
String summary of the PhotonPlayer: player.ID, name and all custom properties of this user.
Use with care and not every frame!
Converts the customProperties to a String on every single call.